package gui.win.initializer;

import core.para.Para;
import gui.utils.Borders;
import gui.utils.FilePicker;
import gui.utils.Slider;
import gui.utils.SliderWrap;
import gui.utils.Window;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.swing.*;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class Initializer extends Window implements ActionListener {

    private FilePicker fReads, rReads, output, lFile;
    private JLabel lab1, lab2, lab3;
    public static JTextArea textArea;
    private JButton copy;

    public Initializer() {
        super(Para.X_AND_Y_APP_LOC, Para.X_AND_Y_APP_LOC, new Dimension(450, 620));
        JPanel p0 = new JPanel();
        p0.setBorder(Borders.getTitledBorder(Borders.STANDARD_TITLED_BORDER, "VTBUILDER PRE LAUNCH"));
        p0.setLayout(new BorderLayout());
        JPanel p1 = new JPanel();
        p1.setEnabled(true);
        p1.setLayout(new BorderLayout());
        JPanel top = new JPanel(new BorderLayout());
        Para.INITILIZER = "y";
        JPanel p2 = new JPanel(new BorderLayout());
        lab1 = new JLabel("<HTML>16 cores minimum recommended. Currently available: <span color=\"red\">"
                + Runtime.getRuntime().availableProcessors()
                + "</span> cores.</HTML>");
        lab1.setFont(Borders.getFont(Borders.GUIFONT));
        lab1.setBorder(BorderFactory.createEmptyBorder(6, 2, 4, 2));
        p2.add(lab1, BorderLayout.NORTH);
        Para.TRDS = Runtime.getRuntime().availableProcessors();
        p2.add(new SliderWrap(Slider.TRDS, 32, 1, Para.TRDS, "Cores To Use", 200, 3), BorderLayout.SOUTH);
        top.add(p2, BorderLayout.CENTER);

        JPanel p3 = new JPanel(new BorderLayout());
        DecimalFormat df = new DecimalFormat("##.##");

        double totMem, totAvailable;
        try {
            com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean();
            totMem = (os.getTotalPhysicalMemorySize() == 0) ? 0 : (double) os.getTotalPhysicalMemorySize() / (1024 * 1024 * 1024);
            //totAvailable = (os.getFreePhysicalMemorySize() == 0) ? 0 : (double) os.getFreePhysicalMemorySize() / (1024 * 1024 * 1024);
        } catch (Exception e) {
            totMem = 0;
            //totAvailable = 0;
        }

        lab2 = new JLabel("<HTML>32 gigabytes of RAM recommended.  Currently installed is <br><span color=\"red\">"
                + df.format(totMem) + " G</span>.</HTML>");

        lab2.setFont(Borders.getFont(Borders.GUIFONT));
        lab2.setBorder(BorderFactory.createEmptyBorder(6, 2, 4, 2));
        p3.add(lab2, BorderLayout.NORTH);
        
        
        if(totMem<96){Para.MEMORY_IN_GIGS = (int)totMem;}
        else{Para.MEMORY_IN_GIGS = 96;}
        
        
        p3.add(new SliderWrap(Slider.MEMORY_IN_GIGS, 96, 4, Para.MEMORY_IN_GIGS, "RAM (gigabytes) To Use", 200, 3), BorderLayout.SOUTH);
        top.add(p3, BorderLayout.SOUTH);

        p1.add(top, BorderLayout.NORTH);

        JPanel middle = new JPanel(new GridLayout(7, 1));
        middle.add(fReads = new FilePicker("Fwd. Reads", true, 22, 120, Para.PATH_TO_FOWARD_READS, FilePicker.PATH_TO_FOWARD_READS));
        middle.add(rReads = new FilePicker("Rev. Reads ",true, 22, 120, (Para.PATH_TO_REVERSE_READS.equals("")?"(optional)":Para.PATH_TO_REVERSE_READS), FilePicker.PATH_TO_REVERSE_READS));
        //middle.add(rReads = new FilePicker("Rev. Reads ",true, 22, 120, (Para.PATH_TO_REVERSE_READS.equals("")?"(optional)":Para.PATH_TO_REVERSE_READS)));
        middle.add(output = new FilePicker("Output", false, 22, 120, Para.PATH_TO_OUTPUT, FilePicker.PATH_TO_OUTPUT));
        middle.add(lFile = new FilePicker("Log", false, 22, 120, Para.PATH_TO_LOGFILE, FilePicker.PATH_TO_LOGFILE));
        middle.add(new SliderWrap(Slider.MNRL, 250, 120, Para.MNRL, "Min. Read Length", 200, 3));
        middle.add(new SliderWrap(Slider.MNTLEN, 400, 150, Para.MNTLEN, "Min. Transcript Length", 200, 3));
        middle.add(new SliderWrap(Slider.CLUST_SEQ_KT_TRANS, 100, 0, Para.CLUST_SEQ_KT_TRANS, "Min. Isoform Similarity (%)", 200, 3));
        p1.add(middle, BorderLayout.CENTER);


        JPanel bottom = new JPanel(new BorderLayout());

        lab3 = new JLabel("<HTML><span color=\"red\">The following command can be used to execute VTBuilder<br> using a console, or"
                + "as part of an analysis pipeline. </span> <br></HTML>");
        lab3.setFont(Borders.getFont(Borders.GUIFONT));
        lab3.setBorder(BorderFactory.createEmptyBorder(4, 2, 4, 2));
        bottom.add(lab3, BorderLayout.NORTH);
        
        textArea = new JTextArea(5, 8);
        setCommand(this.getClass());
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
        textArea.setEditable(true);
        textArea.setLineWrap(true);
        bottom.add(scrollPane, BorderLayout.CENTER);
        bottom.add(getButton(copy = new JButton("UPDATE AND COPY COMMAND TO CLIPBOARD"), 400, 22, new Color(102, 102, 102), new Color(178, 178, 178), this, "UPDATE AND COPY COMMAND TO CLIPBOARD"), BorderLayout.SOUTH);

        p1.add(bottom, BorderLayout.SOUTH);

        p0.add(p1, BorderLayout.NORTH);
        this.add(p0, BorderLayout.CENTER);
        this.add(new Buttons(this), BorderLayout.SOUTH);
        this.setVisible(true);
        //this.setAlwaysOnTop(true);
    }

    public void closeFrame() {
        this.dispose();
    }

    public String getPathToFwdReads() {
        return fReads.getPath();
    }

    public String getPathToRevReads() {
        if (!rReads.getPath().equals(Para.PATH_TO_REVERSE_READS_DEFAULT_VAL)) {
            return rReads.getPath();
        }
        return "";
    }

    public String getPathToOutput() {
        return output.getPath();
    }

    public String getPathToLogFile() {
        return lFile.getPath();
    }

    public static void setCommand(Class cls) {
        String guiCMD = "java -jar -Xmx" + (Para.MEMORY_IN_GIGS*1012) + "M ";
        String consoleCMD = "java -jar -Xmx" + (Para.MEMORY_IN_GIGS*1012) + "M ";
        try{
            guiCMD += cls.getProtectionDomain().getCodeSource().getLocation().getPath();
            consoleCMD += cls.getProtectionDomain().getCodeSource().getLocation().getPath();
            
            guiCMD += " "+Para.K_INIT+" y";
            consoleCMD += " "+Para.K_INIT+" n";
            
            if(!Para.PATH_TO_FOWARD_READS.equals("")){
                guiCMD += " "+Para.K_FWREADS+" " + Para.PATH_TO_FOWARD_READS;
                consoleCMD += " "+Para.K_FWREADS+" " + Para.PATH_TO_FOWARD_READS;
            }
            if(!Para.PATH_TO_REVERSE_READS.equals("")){
                guiCMD += " "+Para.K_RVREADS+" " + Para.PATH_TO_REVERSE_READS;
                consoleCMD += " "+Para.K_RVREADS+" " + Para.PATH_TO_REVERSE_READS;
            }
            guiCMD += " "+Para.K_OUTPUT+" " + Para.PATH_TO_OUTPUT;
            consoleCMD += " "+Para.K_OUTPUT+" " + Para.PATH_TO_OUTPUT;
            
            guiCMD += " "+Para.K_LOG+" " + Para.PATH_TO_LOGFILE;
            consoleCMD += " "+Para.K_LOG+" " + Para.PATH_TO_LOGFILE;
            
            guiCMD += " "+Para.K_TRDS+" " + Para.TRDS;
            consoleCMD += " "+Para.K_TRDS+" " + Para.TRDS;
            
            guiCMD += " "+Para.K_MRL+" " + Para.MNRL;
            consoleCMD += " "+Para.K_MRL+" " + Para.MNRL;
            
            guiCMD += " "+Para.K_MNTLEN+" " + Para.MNTLEN; 
            consoleCMD += " "+Para.K_MNTLEN+" " + Para.MNTLEN;
            
            guiCMD += " "+Para.K_TDIV+" " + Para.CLUST_SEQ_KT_TRANS;
            consoleCMD += " "+Para.K_TDIV+" " + Para.CLUST_SEQ_KT_TRANS;
        }
        catch(Exception e){}
        try {
            if (textArea != null) {
                Para.LAUNCH_COMMAND = guiCMD;
                textArea.setText(consoleCMD);
            }
        } catch (Exception e) {
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == copy) {
            setCommand(this.getClass());
            StringSelection ss = new StringSelection(textArea.getText());
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
        }
    }

    public static JPanel getButton(JButton st, int width, int height, Color fCol, Color bCol, ActionListener al, String tooltip) {
        st.setForeground(fCol);
        st.setBackground(bCol);
        st.setPreferredSize(new Dimension(width, height));
        st.addActionListener(al);
        st.setToolTipText(tooltip);
        JPanel p = new JPanel(new FlowLayout());
        p.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
        p.setOpaque(false);
        p.add(st);
        return p;
    }
}
